package lex.mtd.ui.details;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.*;

import org.lex.swing.ContainerFactory;

import lex.mtd.core.DownloadManager;
import lex.mtd.utils.IReload;

public class DetailsPane extends JPanel implements IReload 
{
	private static final String LOG_CARD = Details.Log.name();
	private static final String THREAD_CARD = Details.Thread.name();
	private static final String GRAPH_CARD = Details.Graph.name();
	private JSplitPane detailsSplitPane;
	// =====================================
	private JTree cardTree;
	// =====================================
	private JPanel cardPane = null;
	private CardLayout card = null;
	private ThreadTable threadTable = null;
	private TabLogSet logPane = null;
	private ProgressPane graphPane = null;
	// =====================================
	private DownloadManager dm = null;

	public DetailsPane()
	{
		super();
		initialize();
	}

	public void setDownloadManager( DownloadManager dm )
	{
		if( null == dm )
			return;
		this.dm = dm;
		this.getThreadTable().setDownloadManager( this.dm );
		this.getGraphPane().setFileBlockSet( dm.getFileSet() );
	}

	private ThreadTable getThreadTable()
	{
		if( null == threadTable )
			threadTable = new ThreadTable();
		return threadTable;
	}

	public TabLogSet getLogPane()
	{
		if( null == logPane )
		{
			logPane = new TabLogSet();
			logPane.setName( getClass().getName() + ".log" );
		}
		return logPane;
	}

	@Override
	public void reload()
	{
		//FIXME ...
		this.getThreadTable().getTableModel().fireTableDataChanged();
		this.getGraphPane().reload();
	}

	private ProgressPane getGraphPane()
	{
		if( null == graphPane )
			graphPane = new ProgressPane();
		return graphPane;
	}

	private JTree getCardTree()
	{
		if( cardTree == null )
		{
			DefaultMutableTreeNode root = new DefaultMutableTreeNode( "Details" );
			Details[] details = Details.values();
			for( Details d : details )
				root.add( new DefaultMutableTreeNode( d ) );
			// =============================================
			cardTree = new JTree( new DefaultTreeModel( root ) );
			cardTree.getSelectionModel()
				.setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION );
			cardTree.setCellRenderer( new DefaultTreeCellRenderer(){
				@Override
				public Component getTreeCellRendererComponent( JTree tree, Object value,
					boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus )
				{
					return super.getTreeCellRendererComponent( tree, value, sel, expanded, false,
						row, hasFocus );
				}
			} );
			cardTree.getSelectionModel().addTreeSelectionListener( new TreeSelectionListener(){
				@Override
				public void valueChanged( TreeSelectionEvent e )
				{
					TreePath path = cardTree.getSelectionPath();
					if( null != path )
					{
						Object node = path.getLastPathComponent();
						if( null != node )
						{
							String card = node.toString();
							getCard().show( getCardPane(), card );
						}
					}
				}
			} );
		}
		return cardTree;
	}

	private void initialize()
	{
		this.setLayout( new BorderLayout() );
		this.add( getDetailsSplitPane(), BorderLayout.CENTER );
	}

	private JPanel getCardPane()
	{
		if( null == cardPane )
		{
			cardPane = new JPanel( this.getCard() );
			cardPane.add( this.getGraphPane(), GRAPH_CARD );
			cardPane.add( new JScrollPane( getThreadTable() ), THREAD_CARD );
			cardPane.add( this.getLogPane(), LOG_CARD );
			card.show( cardPane, THREAD_CARD );
		}
		return cardPane;
	}

	private CardLayout getCard()
	{
		if( null == card )
			card = new CardLayout();
		return card;
	}

	private JSplitPane getDetailsSplitPane()
	{
		if( detailsSplitPane == null )
		{
			detailsSplitPane = ContainerFactory.createBorderlessSplitPane();
			detailsSplitPane.setName( getClass().getName() + ".details" );
			detailsSplitPane.setDividerSize( 5 );
			detailsSplitPane.setResizeWeight( 0.2 );
			detailsSplitPane.setLeftComponent( new JScrollPane( getCardTree() ) );
			detailsSplitPane.setRightComponent( getCardPane() );
		}
		return detailsSplitPane;
	}
}
